package fun.mashuai.generator.plugins.core;

import fun.mashuai.generator.util.StringUtil;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.codegen.mybatis3.javamapper.elements.AbstractJavaMapperMethodGenerator;

import java.text.Annotation;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

/**
 * @author 马帅
 * @version 1.0
 * @className CustomJavaMapperMethodGenerator.java
 * @description 自定义扩展mapper方法
 * @date 2020/4/18 23:38
 */
public class CustomJavaMapperMethodGenerator extends AbstractJavaMapperMethodGenerator {

    @Override
    public void addInterfaceElements(Interface var) {

        // 条件统计方法
        addInterfaceCountByCondition(var);

        // 条件查询方法
        addInterfaceSelectByCondition(var);

        // 批量更新方法
        addInterfaceBatchUpdate(var);
    }

    /**
     * 条件统计方法
     */
    private void addInterfaceCountByCondition(Interface var) {

        // 先创建 import 对象
        Set<FullyQualifiedJavaType> importedTypes = new TreeSet<>();

        // 创建方法对象
        Method method = new Method();

        // 设置该方法为 public
        method.setVisibility(JavaVisibility.PUBLIC);

        // 设置返回类型是 int
        method.setReturnType(FullyQualifiedJavaType.getIntInstance());

        // 设置方法名称
        method.setName("countByCondition");

        // 设置参数类型为实体对象
        FullyQualifiedJavaType parameterType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());

        // import 参数类型对象包
        importedTypes.add(parameterType);

        String tableName = introspectedTable.getTableConfiguration().getTableName();

        // 为方法添加参数，变量名称record
        method.addParameter(new Parameter(parameterType, StringUtil.toCamelCase(tableName)));
        method.addAnnotation("条件统计");

        // 格式化方法注释
        addMapperAnnotations(method);

        context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable);

        var.addImportedTypes(importedTypes);
        var.addMethod(method);
    }

    /**
     * 条件查询方法
     */
    private void addInterfaceSelectByCondition(Interface var) {
        Set<FullyQualifiedJavaType> importedTypes = new TreeSet<>();
        importedTypes.add(FullyQualifiedJavaType.getNewListInstance());
        Method method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);

        // 返回类型是 List
        FullyQualifiedJavaType returnType = FullyQualifiedJavaType.getNewListInstance();

        // 设置泛型实体类对象，并导入包
        FullyQualifiedJavaType listType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
        importedTypes.add(listType);

        // 返回类型添加泛型对象 List<T>
        returnType.addTypeArgument(listType);

        // 加入方法中
        method.setReturnType(returnType);

        // 设置方法名
        method.setName("selectByCondition");

        // 设置方法参数（实体类）
        FullyQualifiedJavaType parameterType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());

        // 添加依赖包
        importedTypes.add(parameterType);

        String tableName = introspectedTable.getTableConfiguration().getTableName();

        // 将参数、变量加入方法
        method.addParameter(new Parameter(parameterType, StringUtil.toCamelCase(tableName)));

        // 设置方法注释
        method.addAnnotation("条件查询");

        // 格式化注释
        addMapperAnnotations(method);

        context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable);

        var.addImportedTypes(importedTypes);
        var.addMethod(method);
    }


    /**
     * 批量更新方法
     */
    private void addInterfaceBatchUpdate(Interface var) {
        Set<FullyQualifiedJavaType> importedTypes = new TreeSet<>();
        Method method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setReturnType(FullyQualifiedJavaType.getIntInstance());
        method.setName("batchUpdate");

        // 设置参数类型是对象
        FullyQualifiedJavaType parameterType = FullyQualifiedJavaType.getNewListInstance();
        importedTypes.add(parameterType);
        FullyQualifiedJavaType listType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
        importedTypes.add(listType);
        parameterType.addTypeArgument(listType);

        // 为方法添加参数，变量名称record
        method.addParameter(new Parameter(parameterType, "list"));
        method.addAnnotation("批量更新");
        method.addAnnotation("");
        method.addAnnotation("主键bigint, 且唯一");

        addMapperAnnotations(method);
        context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable);
        var.addImportedTypes(importedTypes);
        var.addMethod(method);
    }


    /**
     * 格式化方法注释
     */
    private void addMapperAnnotations(Method method) {
        method.getJavaDocLines().clear();

        // 参数
        List<Parameter> parameters = method.getParameters();
        // 注释
        List<String> annotations = method.getAnnotations();

        StringBuilder builder = new StringBuilder();
        builder.append("/**\n");

        if(annotations.size() > 0){
            for(String a : annotations){
                builder.append("     * ").append(a).append("\n");
            }
        }

        if(parameters.size() > 0){
            for(Parameter p : parameters){
                builder.append("     * ").append("@param ").append(p.getName()).append(" ").append(p.getName());
                List<String> an = p.getAnnotations();
                if(an.size() > 0){
                    for(String a : an){
                        builder.append(a).append(" ");
                    }
                }
                builder.append("\n");
            }
        }

        builder.append("     * ").append("@return ").append(method.getReturnType()).append("\n").append("    ").append(" */");

        method.getAnnotations().clear();
        method.addJavaDocLine(builder.toString());
    }

}
